using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using ZoneFiveSoftware.Common.Data.Fitness;
using ZoneFiveSoftware.Common.Data.Measurement;
using ZoneFiveSoftware.Common.Visuals;
using FilteredStatistics.Common;
using FilteredStatistics.Common.Controller;

namespace FilteredStatistics.Data
{
    // This class is only a placeholder to allow us to catch the user's selection
    //  and to then pop a dialog that will take care of asking the user if he wants
    //  to uses recorded laps or distance/time specified laps.  It should never end up
    //  in a FilterList
    class SplitsPlaceholderFilterCriteria : FilterCriteriaFacade
    {
        public SplitsPlaceholderFilterCriteria()
        {
        }

#region FilterCriteriaFacade members

        public override Guid ReferenceId
        {
            get { return GUIDs.SplitsCriteriaGuid; }
        }

        public override IActivity Activity
        {
            set { }
        }

        public override String DisplayName
        {
            get { return CommonResources.Text.LabelSplits; }
        }

        public override bool IsTemplateOnly
        {
            get { return false; }
        }

        public override bool IsMainViewOnly
        {
            get { return true; }
        }

        public override List<object> NamedZones
        {
            get { return null; }
        }

        public override bool IsSerializable
        {
            get { return true; }
        }

        public override UInt16 DataVersion
        {
            get { return Constants.CurrentVersion.VersionNumber; }
        }

        public override object DeserializeCriteria(Stream stream, UInt16 version)
        {
            IFilterCriteria newCriteria = null;
            SerializableInt32Range type = new SerializableInt32Range(0);

            type.Deserialize(stream, new DataVersion(version));
            SplitsCriteriaType splitsType = (SplitsCriteriaType)(Int32)type;

            switch (splitsType)
            {
                case SplitsCriteriaType.RecordedLaps:
                    {
                        newCriteria = new RecordedLapsFilterCriteria(null);
                        break;
                    }
                case SplitsCriteriaType.CustomTime:
                    {
                        newCriteria = new CustomTimeLapsFilterCriteria(null, new TimeSpan(), new TimeSpan());
                        break;
                    }
                case SplitsCriteriaType.CustomDistance:
                    {
                        newCriteria = new CustomDistanceLapsFilterCriteria(null, 0, 0, Length.Units.Kilometer);
                        break;
                    }
            }

            Debug.Assert(newCriteria != null);

            return newCriteria.DeserializeCriteria(stream, version);
        }

        public override void  SerializeCriteria(Stream stream)
        {
            Serialize(stream);
        }

        public override object OnSelectedInList(object previousSelection)
        {
            if(SplitsCriteriaSelected != null)
            {
                // Make sure we have maximum 1 registered object since we have a return value
                Debug.Assert(SplitsCriteriaSelected.GetInvocationList().GetLength(0) == 1);

                IFilterCriteria result;
                SplitsCriteriaSelected(this, previousSelection as IFilterCriteria, out result);

                return result;
            }

            return previousSelection;
        }

#endregion
        
#region IPluginSerializable members

        public override void Serialize(Stream stream)
        {
            // We should never end up with this in a template
            Debug.Assert(false);
        }

#endregion

#region Deserialization methods

        public void Deserialize_V1(Stream stream, DataVersion version)
        {
            // We should never end up with this in a template
            Debug.Assert(false);
        }

#endregion

        public delegate void SplitsCriteriaSelectedEventHandler(SplitsPlaceholderFilterCriteria criteria, IFilterCriteria previousCriteria, out IFilterCriteria resultCriteria);
        public event SplitsCriteriaSelectedEventHandler SplitsCriteriaSelected;
    }
}
